#include "systemparams.h"


SystemParams::SystemParams()
{

}

SystemParams* SystemParams::m_pInstance = nullptr;

SystemParams* SystemParams::instance_get()
{

    if ( m_pInstance == nullptr)

        //判断是否第一次调用
        m_pInstance = new SystemParams();

    return m_pInstance;
}

void SystemParams::system_init()
{
    cacheTaskDir_create();

    for (uint16 i=0; i<CACHE_TASK_NUM_MAX; i++)
    {
        SystemParams::instance_get()->m_cacheIdUsedArray[i] = false;
    }
}

void SystemParams::cacheTaskDir_create()
{
    QString path = QDir::currentPath()+"/"+QString(CACHE_TASK_DIR);
    SystemParams::instance_get()->m_cacheTaskPath =path;

    QDir dir(path);
    if (dir.exists())
    {
        return;
    }

    if (!dir.mkpath(path))
    {
        qWarning("%s dir.mkpath(%s) is failure",__func__,path.toLatin1().data());
    }
}

void SystemParams::cacheIdUsedArray_set(uint16 id, bool used)
{
    uint16 index;
    if (id<1)
    {
        index=0;
    }
    else
    {
        index = id -1;
    }

    SystemParams::instance_get()->m_cacheIdUsedArray[index] = used;
}

uint16 SystemParams::cacheIdUsedArrayEmpty_get()
{
    uint16 i;
    for (i=0; i<CACHE_TASK_NUM_MAX; i++)
    {
        if (SystemParams::instance_get()->m_cacheIdUsedArray[i]==false)
        {
            return i+1;
        }
    }

    return 0;
}

QString SystemParams::blockTypeToString_convert(Block_Info::Block_Type type)
{
    switch(type)
    {
    case Block_Info::IS_DISK:
        return BLOCK_TYPE_DISK;
    case Block_Info::IS_ROM:
        return BLOCK_TYPE_ROM;
    case Block_Info::IS_PARTITION:
        return BLOCK_TYPE_PART;
    }
}

QString SystemParams::cacheTaskStatusToStr_convert(Cache_Task_Status status)
{
    switch (status)
    {
    case CACHE_TASK_STOP:
        return QString::fromUtf8(CACHE_TASK_STOP_STR);
    case CACHE_TASK_RUNNING:
        return QString::fromUtf8(CACHE_TASK_RUNNING_STR);
    }
}

QString SystemParams::cacheTaskUuid_generate()
{
    QTime time;
    time= QTime::currentTime();
    qsrand(time.msec()+time.second()*1000);
    int32 rand1  = qrand();
    int32 rand2  = qrand();
    int32 rand3  = qrand();
    int32 rand4  = qrand();
    QString res = QString("%1%2%3%4").arg(rand1,8,16,QLatin1Char('0'))
                                     .arg(rand2,8,16,QLatin1Char('0'))
                                     .arg(rand3,8,16,QLatin1Char('0'))
                                     .arg(rand4,8,16,QLatin1Char('0'));
    return res;
}

int32 SystemParams::jsonDocument_save(QString &path, QJsonDocument *pJsonDoc)
{
    if (pJsonDoc == nullptr)
    {
        return -1;
    }

    if (path.isEmpty())
    {
        return -2;
    }

    QByteArray byte_array = pJsonDoc->toJson(QJsonDocument::Compact);

    //创建文件对象
    QFile file;
    //关联文件名字
    file.setFileName(path);
    //打开文件,只写方式
    bool isOK = file.open(QIODevice::WriteOnly);
    if (!isOK)
    {
        qWarning("file.open(QIODevice::WriteOnly) error");
        return -3;
    }

    file.write(byte_array.data());

    file.flush();
    file.close();

    return 0;
}

int32 SystemParams::cacheTaskInfoFile_save(QString &path, CacheTaskInfo *pInfo)
{
    QJsonObject json;
    json.insert("task_name",pInfo->m_taskName);
    json.insert("task_index", pInfo->m_taskIndex);
    json.insert("task_uuid",pInfo->m_taskUuid);
    json.insert("task_status",pInfo->m_taskStatus);
    json.insert("block_name",pInfo->m_blockInfo.m_name);
    json.insert("block_type",pInfo->m_blockInfo.m_type);
    json.insert("block_size",pInfo->m_blockInfo.m_size);
    json.insert("block_mounted_point",pInfo->m_blockInfo.m_mountedPoint);
    json.insert("cache_name",pInfo->m_cacheName);
    json.insert("cache_type",pInfo->m_cacheType);
    json.insert("cache_size",static_cast<int>(pInfo->m_cacheSize));
    json.insert("disk_cache_size",pInfo->m_diskCacheSize);
    json.insert("cache_strategy_type",pInfo->m_cacheStrategyType);
    json.insert("granularity_size",static_cast<int>(pInfo->m_granularitySize));

    QJsonDocument document;
    document.setObject(json);

    return jsonDocument_save(path, &document);
}

int32 SystemParams::jsonDocument_get(QString &path, QJsonDocument *pJsonDoc)
{
   if (pJsonDoc == nullptr)
   {
      return -1;
   }

   QFile loadFile(path);
   QByteArray pathArray = path.toLatin1();
   if(!loadFile.open(QIODevice::ReadOnly))
   {
      fprintf(stderr,"could't open %s", pathArray.data());
      return -2;
   }

   QByteArray allData = loadFile.readAll();
   loadFile.close();

   QJsonParseError json_error;
   *pJsonDoc=QJsonDocument::fromJson(allData, &json_error);
   if(json_error.error != QJsonParseError::NoError)
   {
      fprintf(stderr, "parse json error!");
      return -3;
   }

   return 0;
}

int32 SystemParams::cacheTaskInfoFile_get(QString &path, CacheTaskInfo *pInfo)
{
    QJsonDocument jsonDoc;
    QJsonObject myObj;

    qDebug("%s path=%s",__func__, path.toLatin1().data());

    if (pInfo==nullptr)
    {
        return -1;
    }

    if (jsonDocument_get(path, &jsonDoc)!=0)
    {
        fprintf(stderr, "%s jsonDocument_get failure", __func__);
        return -2;
    }

    if (!jsonDoc.isObject())
    {
        fprintf(stderr, "%s json is not object", __func__);
        return -3;
    }

    myObj = jsonDoc.object();
    pInfo->m_taskName = myObj["task_name"].toString();
    pInfo->m_taskIndex = static_cast<uint16>(myObj["task_index"].toInt());
    pInfo->m_taskUuid = myObj["task_uuid"].toString();
    pInfo->m_taskStatus = static_cast<Cache_Task_Status>(myObj["task_status"].toInt());
    pInfo->m_blockInfo.m_name = myObj["block_name"].toString();
    pInfo->m_blockInfo.m_type = static_cast<Block_Info::Block_Type>(myObj["block_type"].toInt());
    pInfo->m_blockInfo.m_size = myObj["block_size"].toString();
    pInfo->m_blockInfo.m_mountedPoint = myObj["block_mounted_point"].toString();
    pInfo->m_cacheName = myObj["cache_name"].toString();
    pInfo->m_cacheType = static_cast<Cache_Type>(myObj["cache_type"].toInt());
    pInfo->m_cacheSize = static_cast<uint32>(myObj["cache_size"].toInt());
    pInfo->m_diskCacheSize = myObj["disk_cache_size"].toString();
    pInfo->m_cacheStrategyType = static_cast<Cache_Strategy_Type>(myObj["cache_strategy_type"].toInt());
    pInfo->m_granularitySize = static_cast<uint32>(myObj["granularity_size"].toInt());

    return 0;
}

void SystemParams::outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{

    static QMutex mutex;

    mutex.lock();

    QString text;

    switch(type)
    {

    case QtDebugMsg:

        text = QString("Debug:");

        break;

    case QtWarningMsg:

        text = QString("Warning:");

        break;

    case QtCriticalMsg:

        text = QString("Critical:");

        break;

    case QtFatalMsg:

        text = QString("Fatal:");
    }

    QString context_info = QString("File:(%1) Line:(%2)").arg(QString(context.file)).arg(context.line);

    QString current_date_time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss ddd");

    QString current_date = QString("(%1)").arg(current_date_time);

    QString message = QString("%1 %2 %3 %4").arg(text).arg(context_info).arg(msg).arg(current_date);

    QFile file("log.txt");

    file.open(QIODevice::WriteOnly | QIODevice::Append);

    QTextStream text_stream(&file);

    text_stream << message << "\r\n";

    file.flush();

    file.close();

    mutex.unlock();
}
